package com.haojiang.mh.widget.chart;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.service.entity.StartEndStateBean;
import com.haojiang.mh.service.entity.StatusBean;
import com.haojiang.mh.utils.ImageUtil;
import com.haojiang.mh.utils.MUtil;
import com.haojiang.mh.utils.SizeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 镜像睡眠周期图表
 * 当前用在《日报》
 */
public class DaySleepCycleChartView extends View {

    private TextPaint textPaint;//文字画笔
    private Paint columnPaint, otherPaint, linePaint, nightPaint;//画笔（other用在遮罩和icon背景圆形图）
    private int columnNumber;//时间段数量
    private int startCoordinate = -1, endCoordinate = -1;//开始坐标和结束坐标
    private float itemWidth;//每个间断的宽度
    //夜晚线高、坐标轴文字高、坐标轴文字宽、坐标轴刻度高、icon背景高、间隔线高、离枕时间文字高
    private int nightHeight, axisTextHeight, axisTextWidth, axisHeight, iconHeight, midLineHeight, leaveTimeHeight;
    private int columnDeep, columnLight, columnRem, columnAwake;//深睡眠、浅睡眠、REM、清醒柱状的高度
    private int columnRoundCorner;//柱状图圆角半径
    private int axisTextSize, innerTextSize;//文本字体大小
    private int width, height, defaultWidth, defaultHeight;//View的宽高、默认宽高度
    //深睡眠、浅睡眠、REM、清醒、离枕、心跳停止对应颜色
    private int deepColor, lightColor, remColor, awakeColor, leaveColor, heartStopColor;
    //间隔线、icon背景、遮罩、坐标轴刻度、夜晚线对应颜色
    private int midLineColor, layerColor, shadowColor, axisColor, nightColor;
    //离枕、心跳停止、夜晚月亮对应Bitmap
    private Bitmap leaveBitmap, heartStopBitmap, moonBitmap;
    //icon上/下、顶部/底部、坐标轴上/下  的间隔距离
    private int iconPadding, viewPadding, axisPadding;
    private RectF columnRectF = new RectF();//矩形

    private List<StartEndStateBean> sleepList;//数据集
    private Bitmap mNodataBitmap;

    public DaySleepCycleChartView(Context context) {
        this(context, null);
    }

    public DaySleepCycleChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DaySleepCycleChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initView(context);
    }

    private void initView(Context context) {

        columnRoundCorner = SizeUtil.dp2px(context, 2);
        nightHeight = SizeUtil.dp2px(context, 15);
        axisTextHeight = SizeUtil.dp2px(context, 30);
        axisTextWidth = SizeUtil.dp2px(context, 40);
        axisHeight = SizeUtil.sp2px(context, 5);
        iconHeight = SizeUtil.dp2px(context, 21);
        midLineHeight = SizeUtil.dp2px(context, 1);
        leaveTimeHeight = SizeUtil.dp2px(context, 11);

        columnDeep = SizeUtil.dp2px(context, 70);
        columnLight = SizeUtil.dp2px(context, 52);
        columnRem = SizeUtil.dp2px(context, 32);
        columnAwake = SizeUtil.dp2px(context, 16);

        iconPadding = SizeUtil.dp2px(context, 8);
        viewPadding = SizeUtil.dp2px(context, 20);
        axisPadding = SizeUtil.dp2px(context, 10);

        defaultWidth = SizeUtil.dp2px(context, 340);

        mNodataBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.img_no_chart_data);
        leaveBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.ic_leave_bed);
        heartStopBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.ic_heart_stop);
        moonBitmap = ImageUtil.getBitmapFromDrawable(context, R.drawable.ic_moon);
        defaultHeight = mNodataBitmap.getHeight();

        deepColor = getResources().getColor(R.color.deepColor);
        lightColor = getResources().getColor(R.color.lightColor);
        remColor = getResources().getColor(R.color.remColor);
        awakeColor = getResources().getColor(R.color.awakeColor);
        leaveColor = getResources().getColor(R.color.green_light);
        heartStopColor = getResources().getColor(R.color.origin_light);
        midLineColor = getResources().getColor(R.color.grey_5);
        layerColor = getResources().getColor(R.color.grey_5);
        shadowColor = getResources().getColor(R.color.grey_4) & 0x7FFFFFFF;
        axisColor = getResources().getColor(R.color.white_half);
        nightColor = getResources().getColor(R.color.purple_3);
        axisTextSize = SizeUtil.sp2px(context, 12);
        innerTextSize = SizeUtil.sp2px(context, 12);

        columnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        columnPaint.setStyle(Paint.Style.FILL);

        otherPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        otherPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setStyle(Paint.Style.FILL);

        nightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        nightPaint.setStyle(Paint.Style.FILL);
        nightPaint.setStrokeWidth(SizeUtil.dp2px(context, 2));

        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (sleepList == null || sleepList.isEmpty() || startCoordinate == -1 || endCoordinate == -1) {
            canvas.drawBitmap(mNodataBitmap, (width - mNodataBitmap.getWidth()) * 0.5f, 0, linePaint);
            return;
        }

        itemWidth = (float) width / columnNumber;
        drawAxis(canvas);//X轴
        drawNightLine(canvas);//夜晚线

        int midLinePosition = viewPadding + iconHeight + iconPadding + columnDeep;
        for (StartEndStateBean ssb : sleepList) {
            if (ssb.getStatus() <= 3) {
                drawColumn(ssb, canvas, midLinePosition);//柱状图
            } else {
                drawLeaveOrHeartStop(ssb, canvas, midLinePosition);//离枕或心跳停止
            }
        }

        /* 间隔线 */
        linePaint.setColor(midLineColor);
        canvas.drawRect(0, midLinePosition, width, midLinePosition + midLineHeight, linePaint);

        /* 绘制阴影遮罩 */
        int shadowBottom = height - viewPadding - nightHeight - axisPadding * 2 - axisTextHeight;
        otherPaint.setColor(shadowColor);
        canvas.drawRect(0, midLinePosition + midLineHeight, width, shadowBottom, otherPaint);
    }

    /**
     * 绘制X轴
     */
    private void drawAxis(Canvas canvas) {
        int startY = height - viewPadding - nightHeight - axisPadding - axisHeight - axisTextHeight;
        int interval;
        if (columnNumber <= 6) {
            interval = 1;
        } else if (columnNumber <= 18) {
            interval = 2;
        } else {
            interval = 3;
        }
        linePaint.setColor(axisColor);
        textPaint.setTextSize(axisTextSize);
        textPaint.setColor(axisColor);
        if (columnNumber == 1) {//只有一个小时，左右刻度+左右靠边时间点
            canvas.drawLine(0, startY, 0, startY + axisHeight, linePaint);
            canvas.drawLine(width, startY, width, startY + axisHeight, linePaint);
            canvas.drawText(
                    String.format(Locale.getDefault(), "%02d:00", startCoordinate % 24),
                    axisTextWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, startY + axisPadding + axisTextHeight, axisTextHeight),
                    textPaint
            );
            canvas.drawText(
                    String.format(Locale.getDefault(), "%02d:00", endCoordinate % 24),
                    width - axisTextWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, startY + axisPadding + axisTextHeight, axisTextHeight),
                    textPaint
            );
        } else {//绘制所有刻度以及除顶末端的刻度文字
            for (int i = 0; i <= columnNumber; i++) {
                int h = (i % 2 == 0) ? axisHeight / 2 : axisHeight;
                canvas.drawLine(i * itemWidth, startY, i * itemWidth, startY + h, linePaint);
                if (i != 0 && i != columnNumber && i % interval == 0) {
                    canvas.drawText(
                            String.format(Locale.getDefault(), "%02d:00", (startCoordinate + i) % 24),
                            itemWidth * i,
                            SizeUtil.getBaseLine(textPaint, startY + axisHeight + axisTextHeight, axisTextHeight),
                            textPaint
                    );
                }
            }
        }
    }

    /**
     * 绘制夜晚线
     */
    private void drawNightLine(Canvas canvas) {
        int nightStart = -1, wholeHour = 0;
        for (int i = 0; i <= columnNumber; i++) {//计算夜晚时间段
            int time = (startCoordinate + i) % 24;
            if (time >= 18 || time <= 6) {
                if (nightStart == -1) {
                    nightStart = time;
                } else {
                    wholeHour++;
                }
            }
        }
        if (nightStart == -1) return;
        if (nightStart < startCoordinate) nightStart += 24;
        float startX = (nightStart - startCoordinate) * itemWidth;
        float endX = (nightStart + wholeHour - startCoordinate) * itemWidth;
        float startY = height - viewPadding - nightHeight * 0.5f;
        nightPaint.setColor(nightColor);
        canvas.drawLine(startX, startY, endX, startY, nightPaint);
        canvas.drawBitmap(
                moonBitmap,
                startX + (endX - startX) * 0.5f - moonBitmap.getWidth() * 0.5f,
                startY - moonBitmap.getHeight() * 0.5f,
                null
        );
    }

    /**
     * 绘制四种睡眠状态的柱状图
     *
     * @param ssb    SleepScrapBean
     * @param canvas 画布
     * @param startY Y起始值
     */
    private void drawColumn(StartEndStateBean ssb, Canvas canvas, int startY) {
        int columnColor = 0, columnH = 0;
        switch (ssb.getStatus()) {
            case 0://深睡眠
                columnColor = deepColor;
                columnH = columnDeep;
                break;
            case 1://浅睡眠
                columnColor = lightColor;
                columnH = columnLight;
                break;
            case 2://REM
                columnColor = remColor;
                columnH = columnRem;
                break;
            case 3://清醒
                columnColor = awakeColor;
                columnH = columnAwake;
                break;
        }
        columnPaint.setColor(columnColor);
        columnRectF.set(
                getXCoordinate(ssb.getStart()),
                startY - columnH,
                getXCoordinate(ssb.getEnd()),
                startY + midLineHeight + columnH
        );
        canvas.drawRoundRect(columnRectF, columnRoundCorner, columnRoundCorner, columnPaint);
    }

    /**
     * 绘制离枕或心跳停止
     */
    private void drawLeaveOrHeartStop(StartEndStateBean ssb, Canvas canvas, int startY) {
        float startX = getXCoordinate(ssb.getStart());
        float endX = getXCoordinate(ssb.getEnd());
        float cx, cy;
        switch (ssb.getStatus()) {
            case 4://离枕
                linePaint.setColor(leaveColor);
                canvas.drawLine(startX, startY - columnDeep, startX, startY + midLineHeight + columnDeep, linePaint);
                canvas.drawLine(endX, startY - columnDeep, endX, startY + midLineHeight + columnDeep, linePaint);
                cx = startX + (endX - startX) * 0.5f;
                cy = startY - columnDeep - iconPadding - iconHeight * 0.5f;
                otherPaint.setColor(layerColor);
                canvas.drawCircle(cx, cy, iconHeight * 0.5f, otherPaint);
                canvas.drawBitmap(leaveBitmap, cx - leaveBitmap.getWidth() * 0.5f, cy - leaveBitmap.getHeight() * 0.5f, null);
                textPaint.setColor(leaveColor);
                textPaint.setTextSize(innerTextSize);
                int leaveTimeBaseLine = startY + midLineHeight + columnDeep + iconPadding + leaveTimeHeight;
                canvas.drawText(
                        getLeaveDuration(startX, endX),
                        cx,
                        SizeUtil.getBaseLine(textPaint, leaveTimeBaseLine, leaveTimeHeight),
                        textPaint
                );
                break;
            case 5://心跳停止
                linePaint.setColor(heartStopColor);
                canvas.drawLine(startX, startY - columnDeep, startX, startY + midLineHeight + columnDeep, linePaint);
                cx = startX;
                cy = startY - columnDeep - iconPadding - iconHeight * 0.5f;
                otherPaint.setColor(layerColor);
                canvas.drawCircle(cx, cy, iconHeight * 0.5f, otherPaint);
                canvas.drawBitmap(heartStopBitmap, cx - heartStopBitmap.getWidth() * 0.5f, cy - heartStopBitmap.getHeight() * 0.5f, null);
                break;
        }
    }

    /**
     * 获取时间轴坐标
     *
     * @param timeString 时间点
     * @return 相对x坐标点
     */
    private float getXCoordinate(String timeString) {
        int duration = MUtil.INSTANCE.getTimeDuration(startCoordinate, timeString, "HH:mm");
        return (float) duration * width / (3600 * columnNumber);
    }

    /**
     * 获取离枕时间长度
     */
    private String getLeaveDuration(float startX, float endX) {
        float duration = (endX - startX) * (3600 * columnNumber) / width;
        duration = Math.max(duration, 60);
        return (int) Math.ceil(duration / 60) + "min";
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    /**
     * 获取X轴坐标个数
     */
    private void getXColumnNumber() {
        if (sleepList == null || sleepList.isEmpty()) return;
        String startTime = sleepList.get(0).getStart();
        if (TextUtils.isEmpty(startTime) || !startTime.contains(":")) {
            startCoordinate = -1;
            return;
        } else {
            startCoordinate = MUtil.INSTANCE.getHourAndMinute(startTime, "HH:mm")[0];
        }
        String endTime = sleepList.get(sleepList.size() - 1).getEnd();
        if (TextUtils.isEmpty(endTime) || !endTime.contains(":")) {
            endCoordinate = -1;
            return;
        } else {
            int[] endHM = MUtil.INSTANCE.getHourAndMinute(endTime, "HH:mm");
            endCoordinate = endHM[0] + (endHM[1] != 0 ? 1 : 0);
        }
        if (startCoordinate == endCoordinate) {
            columnNumber = 24;
        } else {
            columnNumber = endCoordinate - startCoordinate;
            if (endCoordinate < startCoordinate) columnNumber += 24;
        }
    }

    public void setChartDataNew(List<StatusBean> bgData) {
        if (sleepList == null) sleepList = new ArrayList<>();
        sleepList.clear();

        if (bgData != null && !bgData.isEmpty()) {
            List<StartEndStateBean> tempList = new ArrayList<>();
            for (StatusBean data : bgData) {
                StartEndStateBean ses = new StartEndStateBean();
                ses.setStart(MUtil.INSTANCE.getHM(data.getStart()));
                ses.setEnd(MUtil.INSTANCE.getHM(data.getEnd()));
                ses.setStatus(data.getStatus());
                tempList.add(ses);
            }
            sleepList.addAll(tempList);
            getXColumnNumber();
        }

        defaultHeight = viewPadding * 2 + iconHeight + iconPadding * 2 + columnDeep * 2
                + leaveTimeHeight + axisPadding * 2 + axisHeight + axisTextHeight + nightHeight;
        requestLayout();
    }

    public void setChartData(List<StartEndStateBean> data) {
        if (sleepList == null) sleepList = new ArrayList<>();
        sleepList.clear();
        if (data != null && !data.isEmpty()) {
            sleepList.addAll(data);
            getXColumnNumber();
        }

        defaultHeight = viewPadding * 2 + iconHeight + iconPadding * 2 + columnDeep * 2
                + leaveTimeHeight + axisPadding * 2 + axisHeight + axisTextHeight + nightHeight;
        requestLayout();
    }

    public void showNoData() {
        if (sleepList == null) sleepList = new ArrayList<>();
        sleepList.clear();
        defaultHeight = mNodataBitmap.getHeight();
        requestLayout();
    }
}
